"""
权限管理模块
重新设计的权限控制系统
"""

from django.http import JsonResponse
from rest_framework.views import APIView
from django.db.models import Q
from django.views.decorators.csrf import csrf_exempt
from django.utils.decorators import method_decorator
from django.db import transaction
import json

from WxApi import models


def check_admin_permission(username):
    """检查管理员权限"""
    try:
        user = models.User.objects.select_related('Per_group', 'part_id').get(zh_name=username)
        # 管理组(1)可以管理权限
        if user.Per_group.permit == 1:
            return user, None
        else:
            return None, "无管理权限"
    except models.User.DoesNotExist:
        return None, "用户不存在"


def get_user_final_permissions(user):
    """获取用户最终权限列表"""
    # 1. 获取用户个人权限
    user_perms = models.UserApplicationPermission.objects.filter(user=user)
    user_perm_dict = {perm.application_id: perm.is_granted for perm in user_perms}
    
    # 2. 获取角色权限 - 简化查询逻辑
    # 优先获取特定部门权限，如果没有则使用全局权限
    role_perms = models.RoleApplicationPermission.objects.filter(
        permission_group=user.Per_group,
        is_granted=True
    )
    
    # 构建角色权限字典，部门权限优先于全局权限
    role_perm_dict = {}
    for perm in role_perms:
        app_id = perm.application_id
        if app_id not in role_perm_dict:
            role_perm_dict[app_id] = True
        # 如果已有全局权限，部门权限会覆盖
        elif perm.department is not None:
            role_perm_dict[app_id] = True
    
    # 3. 获取所有活跃应用
    applications = models.Application.objects.filter(is_active=True).order_by('sort_order', 'id')
    
    result = []
    for app in applications:
        # 个人权限优先
        if app.id in user_perm_dict:
            has_access = user_perm_dict[app.id]
            permission_source = 'user'
        elif app.id in role_perm_dict:
            has_access = True
            permission_source = 'role'
        else:
            has_access = False
            permission_source = 'none'
        
        result.append({
            'application': app,
            'has_access': has_access,
            'permission_source': permission_source,
            'has_user_override': app.id in user_perm_dict
        })
    
    return result


@method_decorator(csrf_exempt, name='dispatch')
class GetUserApplications(APIView):
    """获取用户可访问的应用列表"""
    
    def post(self, request):
        try:
            data = json.loads(request.body) if request.body else request.POST
            username = data.get('username')
            
            if not username:
                return JsonResponse({'status': False, 'message': '用户名不能为空'})
            
            try:
                user = models.User.objects.select_related('Per_group', 'part_id').get(zh_name=username)
            except models.User.DoesNotExist:
                return JsonResponse({'status': False, 'message': '用户不存在'})
            
            # 获取用户权限
            permissions = get_user_final_permissions(user)
            
            # 只返回有权限的应用
            allowed_apps = []
            for perm in permissions:
                if perm['has_access']:
                    app = perm['application']
                    allowed_apps.append({
                        'id': app.id,
                        'name': app.name,
                        'icon': app.icon,
                        'color': app.color,
                        'url': app.url,
                        'description': app.description,
                        'app_type': app.app_type
                    })
            
            return JsonResponse({
                'status': True,
                'applications': allowed_apps,
                'count': len(allowed_apps)
            })
            
        except Exception as e:
            return JsonResponse({'status': False, 'message': f'获取应用列表失败: {str(e)}'})


@method_decorator(csrf_exempt, name='dispatch')
class GetAllApplications(APIView):
    """获取所有应用列表（管理员用）"""
    
    def post(self, request):
        try:
            data = json.loads(request.body) if request.body else request.POST
            admin_username = data.get('admin_username')
            
            admin_user, error = check_admin_permission(admin_username)
            if error:
                return JsonResponse({'status': False, 'message': error})
            
            applications = models.Application.objects.all().order_by('sort_order', 'id')
            
            app_list = []
            for app in applications:
                app_list.append({
                    'id': app.id,
                    'name': app.name,
                    'icon': app.icon,
                    'color': app.color,
                    'url': app.url,
                    'description': app.description,
                    'app_type': app.app_type,
                    'sort_order': app.sort_order,
                    'is_active': app.is_active,
                    'create_time': app.create_time.strftime('%Y-%m-%d %H:%M:%S')
                })
            
            return JsonResponse({
                'status': True,
                'applications': app_list,
                'count': len(app_list)
            })
            
        except Exception as e:
            return JsonResponse({'status': False, 'message': f'获取应用列表失败: {str(e)}'})


@method_decorator(csrf_exempt, name='dispatch')
class CreateApplication(APIView):
    """创建应用"""
    
    def post(self, request):
        try:
            data = json.loads(request.body) if request.body else request.POST
            admin_username = data.get('admin_username')
            
            admin_user, error = check_admin_permission(admin_username)
            if error:
                return JsonResponse({'status': False, 'message': error})
            
            name = data.get('name', '').strip()
            icon = data.get('icon', 'icon-app')
            color = data.get('color', '#007aff')
            url = data.get('url', '')
            description = data.get('description', '')
            sort_order = int(data.get('sort_order', 0))
            
            if not name:
                return JsonResponse({'status': False, 'message': '应用名称不能为空'})
            
            # 检查名称是否重复
            if models.Application.objects.filter(name=name, is_active=True).exists():
                return JsonResponse({'status': False, 'message': '应用名称已存在'})
            
            app = models.Application.objects.create(
                name=name,
                icon=icon,
                color=color,
                url=url,
                description=description,
                sort_order=sort_order
            )
            
            return JsonResponse({
                'status': True,
                'message': '应用创建成功',
                'application': {
                    'id': app.id,
                    'name': app.name,
                    'icon': app.icon,
                    'color': app.color,
                    'url': app.url,
                    'description': app.description,
                    'sort_order': app.sort_order,
                    'is_active': app.is_active
                }
            })
            
        except Exception as e:
            return JsonResponse({'status': False, 'message': f'创建应用失败: {str(e)}'})


@method_decorator(csrf_exempt, name='dispatch')
class UpdateApplication(APIView):
    """更新应用"""
    
    def post(self, request):
        try:
            data = json.loads(request.body) if request.body else request.POST
            admin_username = data.get('admin_username')
            
            admin_user, error = check_admin_permission(admin_username)
            if error:
                return JsonResponse({'status': False, 'message': error})
            
            app_id = data.get('application_id')
            if not app_id:
                return JsonResponse({'status': False, 'message': '应用ID不能为空'})
            
            try:
                app = models.Application.objects.get(id=app_id)
            except models.Application.DoesNotExist:
                return JsonResponse({'status': False, 'message': '应用不存在'})
            
            name = data.get('name', '').strip()
            if not name:
                return JsonResponse({'status': False, 'message': '应用名��不能为空'})
            
            # 检查名称是否重复（排除自己）
            if models.Application.objects.filter(name=name, is_active=True).exclude(id=app_id).exists():
                return JsonResponse({'status': False, 'message': '应用名称已存在'})
            
            app.name = name
            app.icon = data.get('icon', app.icon)
            app.color = data.get('color', app.color)
            app.url = data.get('url', app.url)
            app.description = data.get('description', app.description)
            app.sort_order = int(data.get('sort_order', app.sort_order))
            app.save()
            
            return JsonResponse({
                'status': True,
                'message': '应用更新成功',
                'application': {
                    'id': app.id,
                    'name': app.name,
                    'icon': app.icon,
                    'color': app.color,
                    'url': app.url,
                    'description': app.description,
                    'sort_order': app.sort_order,
                    'is_active': app.is_active
                }
            })
            
        except Exception as e:
            return JsonResponse({'status': False, 'message': f'更新应用失败: {str(e)}'})


@method_decorator(csrf_exempt, name='dispatch')
class ToggleApplicationStatus(APIView):
    """切换应用状态"""
    
    def post(self, request):
        try:
            data = json.loads(request.body) if request.body else request.POST
            admin_username = data.get('admin_username')
            
            admin_user, error = check_admin_permission(admin_username)
            if error:
                return JsonResponse({'status': False, 'message': error})
            
            app_id = data.get('application_id')
            if not app_id:
                return JsonResponse({'status': False, 'message': '应用ID不能为空'})
            
            try:
                app = models.Application.objects.get(id=app_id)
            except models.Application.DoesNotExist:
                return JsonResponse({'status': False, 'message': '应用不存在'})
            
            app.is_active = not app.is_active
            # 如果是禁用应用，则对RoleApplicationPermission进行更新
            if not app.is_active:
                models.RoleApplicationPermission.objects.filter(application=app).update(is_disabled=True)
            app.save()
            
            return JsonResponse({
                'status': True,
                'message': f'应用已{"启用" if app.is_active else "禁用"}',
                'application': {
                    'id': app.id,
                    'name': app.name,
                    'is_active': app.is_active
                }
            })
            
        except Exception as e:
            return JsonResponse({'status': False, 'message': f'切换应用状态失败: {str(e)}'})


@method_decorator(csrf_exempt, name='dispatch')
class GetDepartmentUsers(APIView):
    """获取部门用户列表"""
    
    def post(self, request):
        try:
            data = json.loads(request.body) if request.body else request.POST
            admin_username = data.get('admin_username')
            
            admin_user, error = check_admin_permission(admin_username)
            if error:
                return JsonResponse({'status': False, 'message': error})
            
            # 获取所有部门和用户
            departments = models.Department.objects.all().order_by('order_num', 'dept_id')
            users = models.User.objects.filter(is_active_bool=True).select_related('Per_group', 'part_id')
            
            # 按部门分组
            dept_users = {}
            for user in users:
                dept_id = user.part_id.dept_id if user.part_id else 15
                if dept_id not in dept_users:
                    dept_users[dept_id] = []
                
                # 计算用户权限统计
                permissions = get_user_final_permissions(user)
                access_count = sum(1 for p in permissions if p['has_access'])
                total_count = len(permissions)
                
                dept_users[dept_id].append({
                    'id': user.id,
                    'zh_name': user.zh_name,
                    'permission_group': {
                        'id': user.Per_group.permit,
                        'name': user.Per_group.get_permit_display()
                    },
                    'wx_avatar_url': user.wx_avatar_url,
                    'access_count': access_count,
                    'total_count': total_count
                })
            
            # 构建返回数据
            result = []
            for dept in departments:
                users_in_dept = dept_users.get(dept.dept_id, [])
                if users_in_dept:  # 只返回有用户的部门
                    result.append({
                        'id': dept.dept_id,
                        'name': dept.dept_name,
                        'users': users_in_dept,
                        'user_count': len(users_in_dept)
                    })
            
            return JsonResponse({
                'status': True,
                'departments': result
            })
            
        except Exception as e:
            print(f"Error in GetDepartmentUsers: {str(e)}")
            return JsonResponse({'status': False, 'message': f'获取部门用户失败: {str(e)}'})


@method_decorator(csrf_exempt, name='dispatch')
class GetUserPermissions(APIView):
    """获取用户权限详情"""
    
    def post(self, request):
        try:
            data = json.loads(request.body) if request.body else request.POST
            admin_username = data.get('admin_username')
            target_user_id = data.get('target_user_id')
            
            admin_user, error = check_admin_permission(admin_username)
            if error:
                return JsonResponse({'status': False, 'message': error})
            
            if not target_user_id:
                return JsonResponse({'status': False, 'message': '用户ID不能为空'})
            
            try:
                target_user = models.User.objects.select_related('Per_group', 'part_id').get(id=target_user_id)
            except models.User.DoesNotExist:
                return JsonResponse({'status': False, 'message': '用户不存在'})
            
            # 获取用户权限详情
            permissions = get_user_final_permissions(target_user)
            
            app_permissions = []
            for perm in permissions:
                app = perm['application']
                app_permissions.append({
                    'id': app.id,
                    'name': app.name,
                    'icon': app.icon,
                    'color': app.color,
                    'description': app.description,
                    'has_access': perm['has_access'],
                    'permission_source': perm['permission_source'],
                    'has_user_override': perm['has_user_override']
                })
            
            return JsonResponse({
                'status': True,
                'user': {
                    'id': target_user.id,
                    'zh_name': target_user.zh_name,
                    'permission_group': {
                        'id': target_user.Per_group.permit,
                        'name': target_user.Per_group.get_permit_display()
                    },
                    'department': {
                        'id': target_user.part_id.dept_id,
                        'name': target_user.part_id.dept_name
                    },
                    'wx_avatar_url': target_user.wx_avatar_url
                },
                'applications': app_permissions
            })
            
        except Exception as e:
            return JsonResponse({'status': False, 'message': f'获取用户权限失败: {str(e)}'})


@method_decorator(csrf_exempt, name='dispatch')
class UpdateUserPermissions(APIView):
    """更新用户权限"""
    
    def post(self, request):
        try:
            data = json.loads(request.body) if request.body else request.POST
            admin_username = data.get('admin_username')
            target_user_id = data.get('target_user_id')
            permissions = data.get('permissions', [])
            
            admin_user, error = check_admin_permission(admin_username)
            if error:
                return JsonResponse({'status': False, 'message': error})
            
            if not target_user_id:
                return JsonResponse({'status': False, 'message': '用户ID不能为空'})
            
            try:
                target_user = models.User.objects.select_related('Per_group', 'part_id').get(id=target_user_id)
            except models.User.DoesNotExist:
                return JsonResponse({'status': False, 'message': '用户不存在'})
            
            # 使用事务处理权限更新
            with transaction.atomic():
                for perm_data in permissions:
                    app_id = perm_data.get('app_id')
                    action = perm_data.get('action')  # 'grant', 'deny', 'remove'
                    
                    try:
                        app = models.Application.objects.get(id=app_id)
                    except models.Application.DoesNotExist:
                        continue
                    
                    if action == 'remove':
                        # 删除个人权限设置，恢复为跟随角色权限
                        models.UserApplicationPermission.objects.filter(
                            user=target_user,
                            application=app
                        ).delete()
                    else:
                        # 创建或更新个人权限
                        perm, created = models.UserApplicationPermission.objects.get_or_create(
                            user=target_user,
                            application=app,
                            defaults={
                                'permission_group': target_user.Per_group,
                                'department': target_user.part_id,
                                'is_granted': action == 'grant'
                            }
                        )
                        
                        if not created:
                            perm.is_granted = action == 'grant'
                            perm.save()
            
            return JsonResponse({
                'status': True,
                'message': '权限更新成功'
            })
            
        except Exception as e:
            return JsonResponse({'status': False, 'message': f'更新权限失败: {str(e)}'})


@method_decorator(csrf_exempt, name='dispatch')
class GetRolePermissions(APIView):
    """获取角色权限列表"""
    
    def post(self, request):
        try:
            data = json.loads(request.body) if request.body else request.POST
            admin_username = data.get('admin_username')
            
            admin_user, error = check_admin_permission(admin_username)
            if error:
                return JsonResponse({'status': False, 'message': error})
            
            # 获取所有权限组
            permission_groups = models.Permission_group.objects.all().order_by('permit')
            
            roles = []
            for group in permission_groups:
                # 获取该角色的权限数量
                role_perms = models.RoleApplicationPermission.objects.filter(
                    is_disabled=False,
                    permission_group=group,
                    is_granted=True
                ).values('application_id').distinct().count()
                print(f"  角色: {group.get_permit_display()} 权限数: {role_perms}")
                roles.append({
                    'id': group.permit,
                    'name': group.get_permit_display(),
                    'permission_count': role_perms
                })
            
            return JsonResponse({
                'status': True,
                'roles': roles
            })
            
        except Exception as e:
            return JsonResponse({'status': False, 'message': f'获取角色权限失败: {str(e)}'})


@method_decorator(csrf_exempt, name='dispatch')
class GetRoleApplications(APIView):
    """获取角色的应用权限详情"""
    
    def post(self, request):
        try:
            data = json.loads(request.body) if request.body else request.POST
            admin_username = data.get('admin_username')
            role_id = data.get('role_id')
            
            admin_user, error = check_admin_permission(admin_username)
            if error:
                return JsonResponse({'status': False, 'message': error})
            
            if not role_id:
                return JsonResponse({'status': False, 'message': '角色ID不能为空'})
            
            try:
                role = models.Permission_group.objects.get(permit=role_id)
            except models.Permission_group.DoesNotExist:
                return JsonResponse({'status': False, 'message': '角色不存在'})
            
            # 获取该角色的权限
            role_perms = models.RoleApplicationPermission.objects.filter(
                permission_group=role,
                is_granted=True
            )
            role_perm_set = set(role_perms.values_list('application_id', flat=True))
            
            # 获取所有活跃应用
            applications = models.Application.objects.filter(is_active=True).order_by('sort_order', 'id')
            
            app_list = []
            for app in applications:
                app_list.append({
                    'id': app.id,
                    'name': app.name,
                    'icon': app.icon,
                    'color': app.color,
                    'description': app.description,
                    'has_permission': app.id in role_perm_set
                })
            
            return JsonResponse({
                'status': True,
                'role': {
                    'id': role.permit,
                    'name': role.get_permit_display()
                },
                'applications': app_list
            })
            
        except Exception as e:
            return JsonResponse({'status': False, 'message': f'获取角色应用权限失败: {str(e)}'})


@method_decorator(csrf_exempt, name='dispatch')
class UpdateRolePermissions(APIView):
    """更新角色权限"""
    
    def post(self, request):
        try:
            data = json.loads(request.body) if request.body else request.POST
            admin_username = data.get('admin_username')
            role_id = data.get('role_id')
            permissions = data.get('permissions', [])
            
            admin_user, error = check_admin_permission(admin_username)
            if error:
                return JsonResponse({'status': False, 'message': error})
            
            if not role_id:
                return JsonResponse({'status': False, 'message': '角色ID不能为空'})
            
            try:
                role = models.Permission_group.objects.get(permit=role_id)
            except models.Permission_group.DoesNotExist:
                return JsonResponse({'status': False, 'message': '角色不存在'})
            
            # 使用事务处理权限更新
            with transaction.atomic():
                for perm_data in permissions:
                    app_id = perm_data.get('app_id')
                    action = perm_data.get('action')  # 'grant', 'revoke'
                    
                    try:
                        app = models.Application.objects.get(id=app_id)
                    except models.Application.DoesNotExist:
                        continue
                    
                    if action == 'revoke':
                        # 撤销权限
                        models.RoleApplicationPermission.objects.filter(
                            permission_group=role,
                            application=app
                        ).delete()
                    elif action == 'grant':
                        # 授权
                        perm, created = models.RoleApplicationPermission.objects.get_or_create(
                            permission_group=role,
                            application=app,
                            defaults={
                                'is_granted': True,
                                'department': None  # 全局权限
                            }
                        )
                        
                        if not created:
                            perm.is_granted = True
                            perm.save()
            
            return JsonResponse({
                'status': True,
                'message': '角色权限更新成功'
            })
            
        except Exception as e:
            return JsonResponse({'status': False, 'message': f'更新角色权限失败: {str(e)}'})